<?php

/**
 * @package 
 * 
 * @version 1.0
 * @copyright 1997-2014 The PHP Group
 * @author itharry<61647649@qq.com> 
 * @created time 2014-07-21
 */
class cls_redis
{
    /**
     *  redis链接标识符号
     */
    protected static $redis   = NULL;

    /**
     *  默认redis前缀
     */
    protected static $prefix  = "3kwan";

    /**
     *  默认链接超时时间
     */
    protected static $timeout = 30;

    /**
     *  错误状态码
     */
    public static $errno   = 0;

    /**
     *  错误信息
     */
    public static $error   = "";

    protected static function init()
    {
        // 如果当前链接标识符为空，或者ping不同，就close之后重新打开
        if ( empty(self::$redis) || !self::ping() )
        {
            try
            {
                $config = config('REDIS_CONF');
                // 如果没有此redis配置，直接抛异常
                if ( !isset($config) ) 
                {
                    throw new Exception("Unknown redis server!!");
                }

                // 如果当前已经有链接标识符，但是ping不了，则先关闭
                if ( !empty(self::$redis) )
                {
                    self::$redis->close();
                }

                // 创建连接符
                self::$prefix  = empty($config['prefix']) ? self::$prefix : $config['prefix'];
                self::$timeout = empty($config['timeout']) ? self::$timeout : $config['timeout'];

                self::$redis = new Redis();
                self::$redis->pconnect($config['host'], $config['port'], $config['timeout']);
                self::$redis->setOption(Redis::OPT_PREFIX, self::$prefix . ":");
            }
            catch (Exception $e)
            {
                self::$errno = $e->getCode();
                self::$error = $e->getMessage();
            }
        }

        return self::$redis;
    }

    /**
     * set
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param string $key
     * @param string $value
     * @param int $expire
     * @static 
     */
    public static function set($key, $value, $expire = 0)
    {
        $redis = self::init();

        if ($redis) 
        {
            $key = self::_get_key($key, self::$prefix);

            if ($expire > 0)
            {
                return $redis->setex($key, $expire, $value);
            }
            else
            {
                return $redis->set($key, $value);
            }
        }

        return NULL;
    }

    /**
     * get
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     */
    public static function get( $key)
    {
        $redis = self::init();

        if ( $redis )
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->get($key);
        }

        return NULL;
    }

    /**
     * del 删除数据
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function del($key)
    {
        $redis = self::init();

        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->del($key);
        }

        return NULL;
    }

    /**
     * lpush 将数据从左边压入
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $value
     * @static 
     * @return void
     */
    public static function lpush($key, $value)
    {
        try
        {
            $redis = self::init();

            if ($redis)
            {
                $key = self::_get_key($key, self::$prefix);
                return $redis->lpush($key, $value);
            }
        }
        catch(Exception $e)
        {
            log::out("redis[lpush]", $e->getMessage());
        }

        return NULL;
    }

    /**
     * rpush 将数据从右边压入
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $value
     * @static 
     * @return void
     */
    public static function rpush($key, $value)
    {
        $redis = self::init();

        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->rpush($key, $value);
        }
        return NULL;
    }

    /**
     * lpop 从左边弹出数据, 并删除数据
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function lpop($key)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->lpop($key);
        }
        return NULL;
    }

    /**
     * rpop
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function rpop($key)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->rpop($key);
        }
        return NULL;
    }

    /**
     * lsize 长度
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function lsize($key)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->lSize($key);
        }
        return NULL;
    }

    /**
     * lget 获取数据
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param int $index
     * @static 
     * @return void
     */
    public static function lget($key, $index = 0)
    {
        $redis = self::init() ;
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->lget($key, $index);
        }
        return NULL;
    }

    /**
     * lRange 获取范围数据
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $start
     * @param mixed $end
     * @static 
     * @return void
     */
    public static function lRange($key, $start, $end)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->lRange($key, $start, $end);
        }
        return NULL;
    }

    /**
     * ttl 返回某个KEY的过期时间 
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function ttl($key)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->ttl($key);
        }
        return NULL;
    }

    /**
     * expire 为某个key设置过期时间,同setTimeout
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $expire
     * @static 
     * @return void
     */
    public static function expire($key, $expire)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = self::_get_key($key, self::$prefix);
            return $redis->expire($key, $expire);
        }
        return NULL;
    }

    /**
     * exists 是否存在
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @static 
     * @return void
     */
    public static function exists($key)
    {
        $redis = self::init();
        if ($redis)
        {
            $key = get_key($key, self::$prefix);
            return $redis->exists($key);
        }
        return false;
    }

    /**
     * _get_key 获取真实KEY
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $prefix
     * @static 
     * @return void
     */
    private static function _get_key($key, $prefix)
    {
        return empty($prefix) ? $key : ($prefix.":".$key);
    }    

    /**
     * ping 检查当前redis是否存在且是否可以连接上
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @static 
     * @return void
     */
    protected static function ping()
    {
        try
        {
            if ( empty (self::$redis) )
            {
                return false;
            }
            return self::$redis->ping() == '+PONG';
        }
        catch(Exception $e)
        {
            return false;
        }
    }

    /**
     * rlist 从底部抽书数据并删除
     * 
     * @author itharry <61647649@qq.com> 
     * @created time 2014-07-14
     * @param mixed $key
     * @param mixed $length
     * @return void
     */
    public static function rlist($key, $length)
    {
        try
        {
            $queue_length = self::lsize($key);
            // 如果队列中有数据
            if ($queue_length > 0)
            {
                $list = array();
                $count = ($queue_length >= $length) ? $length : $queue_length;
                for ($i = 0; $i < $count; $i++) 
                {
                    $data = self::rpop($key);
                    if ($data === false)
                    {
                        continue;
                    }

                    $list[] = $data;
                }
                return $list;
            }
            else
            {
                // 没有数据返回NULL
                return NULL;
            }
        }
        catch (Exception $e)
        {
            self::$errno = $e->getCode();
            self::$error = $e->getMessage();
        }
    }

    public static function debug()
    {
        return array(self::$errno, self::$error);
    }
}

